﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 属性字典
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SUAttributeDictionaryRef 的包装</remarks>
    public class AttributeDictionary : Entity
    {
        #region API 函数
        /// <summary>
        /// 创建一个属性字典
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryCreate(out IntPtr dictionary, [MarshalAs(UnmanagedType.LPUTF8Str)] string name);

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="dictionary"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryRelease(ref IntPtr dictionary);

        /// <summary>
        /// 字典的名字
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryGetName(IntPtr dictionary, ref IntPtr name);

        /// <summary>
        /// 设置键值
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="value_in"><see cref="TypedValue"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionarySetValue(IntPtr dictionary, [MarshalAs(UnmanagedType.LPUTF8Str)] string key, IntPtr value_in);

        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="value_out"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryGetValue(IntPtr dictionary, [MarshalAs(UnmanagedType.LPUTF8Str)] string key, out IntPtr value_out);

        /// <summary>
        /// 获取键的个数
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryGetNumKeys(IntPtr dictionary, out int count);

        /// <summary>
        /// 获取全部键值
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="len"></param>
        /// <param name="keys"></param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUAttributeDictionaryGetKeys(IntPtr dictionary, int len, IntPtr[] keys, out int realcount);
        #endregion

        /// <summary>
        /// 字典的名字
        /// </summary>
        public string Name
        {
            get
            {
                StringRef s = StringRef.Empty;
                SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryGetName(Id, ref s.Id));
                return s.Dispose();
            }
        }

        /// <summary>
        /// 键值对的个数
        /// </summary>
        public int Count
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryGetNumKeys(Id, out int c));
                return c;
            }
        }

        /// <summary>
        /// 全部属性名
        /// </summary>
        public List<string> Keys
        {
            get
            {
                IntPtr[] pts = new IntPtr[Count];
                SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryGetKeys(Id, pts.Length, pts, out _));
                return pts.Select(i => new StringRef() { Id = i }.Dispose()).ToList();
            }
        }

        /// <summary>
        /// 键对应的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public TypedValue this[string key]
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryGetValue(Id, key, out IntPtr value));
                return new TypedValue(value);
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionarySetValue(Id, key, value.Id));
            }
        }

        /// <summary>
        /// 创建字典
        /// </summary>
        /// <param name="name"></param>
        public AttributeDictionary(string name)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryCreate(out Id, name));
        }

        internal AttributeDictionary(IntPtr id) : base(id) { }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUAttributeDictionaryRelease(ref Id));
        }
    }
}